package com.mxin.ui.list

import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.widget.FrameLayout
import android.widget.LinearLayout
import androidx.recyclerview.widget.RecyclerView
import com.scwang.smart.refresh.layout.SmartRefreshLayout
import com.scwang.smart.refresh.layout.api.RefreshLayout


class BaseListViewHelper<T> : IListView<T>, IRefreshBinding {


    private lateinit var recyclerView: RecyclerView
    private lateinit var refreshView : RefreshLayout
    private var hasRefreshLayout = false
    private var subscribes:MutableList<(PageData<T>)->Unit>? = null

    //分页的页数
    private var currPage = Page()

    /**
     * 绑定ListView 并且 初始化ListView
     */
    override fun bindListView(view: View, config:((rv:RecyclerView)->Unit)?):RecyclerView {
        when (view) {
            is RecyclerView -> {
                recyclerView = view
            }
            is ViewGroup -> {
                //如果传的是viewGroup。那么自动创建RecyclerView并填充到viewGroup中
                recyclerView = RecyclerView(view.context)
                view.addView(recyclerView, getMaxSizeLayoutParams(view))
            }
            else -> {
                throw IllegalAccessException("自动填充ListView的view必须为ViewGroup！")
            }
        }
        //设置Recyclerview
        config?.invoke(recyclerView)
        return recyclerView
    }

    //订阅数据的变化
    fun subscribeData(sub:(PageData<T>)->Unit){
        if(subscribes==null){
            subscribes = mutableListOf()
        }
        subscribes?.add(sub)
    }

    override fun emit(t: PageData<T>) {
        val dataSource = recyclerView.adapter
        //缓存当前列表的分页
        if(hasRefreshLayout && t.data!=null){
            currPage = t.page
        }
        if(dataSource is DataSource<*>){
            if(t.getPage()<=0){
                // 设置刷新控件状态
                if(hasRefreshLayout && refreshView.isRefreshing){
                    refreshView.finishRefresh(t.state != PageDataState.Null)
                    //下拉刷新，数据>=pageSize时，可以加载更多
                    refreshView.setNoMoreData(t.state != PageDataState.Match)
                }
                //提交数据到列表控件
                dataSource.setData(t.data as List<Nothing>?)
            }else{
                // 设置刷新控件状态
                if(hasRefreshLayout && refreshView.isLoading){
                    if(t.data!=null && t.data.size >= t.getPageSize()){
                        //数据等于pageSize，还有下一页
                        refreshView.finishRefresh(true)
                    }else if(t.data!=null){
                        //数据不满一页，没有下一页
                        refreshView.finishLoadMoreWithNoMoreData()
                    }else{
                        //获取数据失败，等于null
                        refreshView.finishLoadMore(false)
                    }
                    refreshView.finishLoadMore(t.data?.isNotEmpty()==true)
                }
                //提交数据到列表控件
                dataSource.addData(t.data as List<Nothing>?)
            }
        }
        //如果有需要订阅了数据，那么分发下去
        subscribes?.forEach { it.invoke(t) }
    }


    private fun getMaxSizeLayoutParams(view: ViewGroup): ViewGroup.LayoutParams {
        return when(view){
            is FrameLayout ->{
                FrameLayout.LayoutParams(MATCH_PARENT,MATCH_PARENT)
            }
            is LinearLayout ->{
                LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
            }
            else ->{
                ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)
            }
//            else -> throw IllegalAccessException("自动填充ListView的view不能匹配到LayoutParams")
        }
    }

    override fun bindRefreshLayout(view:View, refreshListener: IRefreshListener, config:((rL: RefreshLayout)->Unit)?):RefreshLayout{
        when (view) {
            is RefreshLayout -> {
                refreshView = view
            }
            is RecyclerView -> {
                //如果传的是RecyclerView。那么自动创建RefreshLayout,然后将RefreshLayout插入到RecyclerView和它的父类中间
                val parentView = view.parent as ViewGroup
                parentView.removeView(view)
                refreshView = SmartRefreshLayout(view.context)
                        .apply {
                            addView(view, getMaxSizeLayoutParams(this))
                            parentView.addView(this, getMaxSizeLayoutParams(parentView))
                        }
            }
            is ViewGroup -> {
                //如果传的是viewGroup。那么自动创建RefreshLayout并填充到viewGroup中
                refreshView = SmartRefreshLayout(view.context)
                        .apply {
                            view.addView(this, getMaxSizeLayoutParams(view))
                        }
            }
            else -> {
                throw IllegalAccessException("自动填充SmartRefreshLayout的view必须为ViewGroup！")
            }
        }
        hasRefreshLayout = true
        refreshView.setOnRefreshListener { refreshListener.refresh(currPage.head()) }
        refreshView.setOnLoadMoreListener { refreshListener.loadMore(currPage.next()) }
        //设置Recyclerview
        config?.invoke(refreshView)
        return refreshView
    }

}